﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace HML.Design
{
    /// <summary>
    /// SingleAccordion控件设计模式行为
    /// </summary>
    public class SingleAccordionDesigner : ControlDesigner
    {
        #region 字段

        /// <summary>
        /// 鼠标左键按下节点
        /// </summary>
        private SingleAccordionCategoryNode mouseLeftDownObject = null;

        private const int WM_LBUTTONDOWN = 0x0201; //按下鼠标左键 
        private const int WM_LBUTTONUP = 0x0202; //释放鼠标左键

        #endregion

        #region 重写

        protected override void OnPaintAdornments(PaintEventArgs pe)
        {
            base.OnPaintAdornments(pe);

            // 绘制虚线边框
            SingleAccordion control = (SingleAccordion)this.Control;
            if (!control.BorderVisible)
            {
                Pen pen = new Pen((double)control.BackColor.GetBrightness() >= 0.5 ? ControlPaint.Dark(control.BackColor) : ControlPaint.Light(control.BackColor)) { DashStyle = DashStyle.Dash };
                pe.Graphics.DrawRectangle(pen, new Rectangle(control.ClientRectangle.X, control.ClientRectangle.Y, control.ClientRectangle.Width - 1, control.ClientRectangle.Height - 1));
                pen.Dispose();
            }
        }

        public override void InitializeNewComponent(IDictionary defaultValues)
        {
            base.InitializeNewComponent(defaultValues);

            SingleAccordionCategoryNode category1 = new SingleAccordionCategoryNode() { Text = "类别1" };
            category1.Childrens.Add(new SingleAccordionContentNode() { Text = "内容1" });
            category1.Childrens.Add(new SingleAccordionContentNode() { Text = "内容2" });

            SingleAccordionCategoryNode category2 = new SingleAccordionCategoryNode() { Text = "类别2" };
            category2.Childrens.Add(new SingleAccordionContentNode() { Text = "内容1" });
            category2.Childrens.Add(new SingleAccordionContentNode() { Text = "内容2" });
            SingleAccordion singleAccordion = (SingleAccordion)this.Component;

            MemberDescriptor member1 = (MemberDescriptor)TypeDescriptor.GetProperties((object)this.Component)["Nodes"];
            this.RaiseComponentChanging(member1);
            singleAccordion.Nodes.Add(category1);
            singleAccordion.Nodes.Add(category2);
            this.RaiseComponentChanged(member1, (object)null, (object)null);
        }

        /// <summary>
        /// 试图设计器初始化控件实例
        /// </summary>
        /// <param name="component"></param>
        public override void Initialize(IComponent component)
        {
            base.Initialize(component);

            SingleAccordion singleAccordion = component as SingleAccordion;
            if (singleAccordion != null)
            {
                singleAccordion.LostFocus += this.SingleAccordion_LostFocus;
            }
        }

        /// <summary>
        /// 指示该控件是否应处理在指定点单击鼠标的操作
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        protected override bool GetHitTest(Point point)
        {
            SingleAccordion control = (SingleAccordion)this.Control;
            return control.HitTestSroll(this.Control.PointToClient(point));
        }

        /// <summary>
        /// 处理 Windows 消息，并可以选择将其路由到控件。
        /// </summary>
        /// <param name="m"></param>
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_LBUTTONDOWN)
            {
                SingleAccordion control = (SingleAccordion)this.Control;
                this.mouseLeftDownObject = control.HitTestCategoryNode(control.PointToClient(Control.MousePosition));
            }
            else if (m.Msg == WM_LBUTTONUP)
            {
                SingleAccordion control = (SingleAccordion)this.Control;
                if (this.mouseLeftDownObject != null && this.mouseLeftDownObject == control.HitTestCategoryNode(control.PointToClient(Control.MousePosition)))
                {
                    this.mouseLeftDownObject.Expand = !this.mouseLeftDownObject.Expand;
                }
                this.mouseLeftDownObject = null;
            }

            base.WndProc(ref m);
        }

        #endregion

        #region  私有方法

        /// <summary>
        /// 控件失去焦点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SingleAccordion_LostFocus(object sender, EventArgs e)
        {
            this.mouseLeftDownObject = null;
        }

        #endregion

    }
}
